<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./vue/vue.js"></script>
  </head>
  <body>
    <pre>
      vue2响应式丢失的场景和解决方法
        1. 对象新增属性，通过$set解决
        2. 数组覆盖length，避免使用length赋值操作
        3. 数组的下标操作，转用变更方法
    </pre>
    <div id="app">
      <p>user:{{ user }}</p>
      <input type="text" v-model="user.name" />
      <br />
      <input type="button" value="添加age属性" @click="addUserAge()" />
      <input type="button" value="添加sex属性" @click="addUserSex()" />
      <hr />
      <p>arr:{{ arr }}</p>
      <input type="button" value="清空数组" @click="clearArr()" />
      <input
        type="button"
        value="在数组末尾增加新的元素"
        @click="pushNewItem()"
      />
    </div>
    <script>
      new Vue({
        el: "#app",
        data: {
          // 对象的属性是有限的，所以对象会被递归劫持构建响应式
          user: {
            name: "tom",
          },
          // 数组的元素可能会存在很多，并且运行时会被频繁的删除，添加，
          //      所以vue对数组做数据劫持，但对元素不做数据劫持
          arr: [100, 200, 300],
        },
        methods: {
          addUserAge() {
            // 在user中添加一个新属性age
            // 1. 在vue完成实例构建之后，为对象增加新属性，新加的属性不具有响应式=>响应式丢失
            this.user.age = 23;
          },
          addUserSex() {
            // console.log(this.$set);
            // 通过$set方法可以实现为对象增加具有响应式的属性
            // this.$set(targetObj,porpName,propValue)
            this.$set(this.user, "sex", "男");
          },
          clearArr() {
            // 下述代码是对整个数组进行重新赋值，触发响应式
            // this.arr = [];
            // 下述代码操作的数组元素，未修改数组对象，不触发响应式
            this.arr.length = 0;
          },
          pushNewItem() {
            // 下述代码操作的数组元素，未修改数组对象，触发响应式
            // vue通过修改数组的原型方法，将以下方法在保留原有功能的情况下，增加响应式触发，所以可以触发响应功能
            // 变更方法
            //      push()
            //      pop()
            //      shift()
            //      unshift()
            //      splice()
            //      sort()
            //      reverse()
            //      this.arr.push(Math.random());
            // 下述代码操作的数组元素，未修改数组对象，不触发响应式
            let i = this.arr.length;
            this.arr[i] = Math.random();
          },
        },
      });
    </script>
  </body>
</html>
